package com.cqeec.aspect;

import cn.hutool.core.io.FileUtil;
import cn.hutool.poi.excel.ExcelUtil;
import cn.hutool.poi.excel.ExcelWriter;
import com.cqeec.annotation.ExportExcel;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.stereotype.Component;

import java.lang.reflect.Method;
import java.util.List;


/**
 * 导出切面类
 */
@Aspect
@Component
public class ExportExcelAspect {

    /**
     * 环绕通知
     */
    @Around("@annotation(com.cqeec.annotation.ExportExcel)")
    public Object afterAdvice(ProceedingJoinPoint joinPoint) {
        // 获取方法
        Method method = ((MethodSignature) joinPoint.getSignature()).getMethod();
        ExportExcel exportExcel = method.getAnnotation(ExportExcel.class);
        String methodName = method.getName();

        // 执行目标方法
        Object returnValue = null;
        try {
            returnValue = joinPoint.proceed();
        } catch (Throwable e) {
            System.out.println("环绕方法执行异常");
            throw new RuntimeException(e);
        }

        // 返回值为空，并且不属于 List 集合则报错
        if (returnValue == null) {
            throw new RuntimeException(methodName + " 方法返回值不能为空");
        }
        if (!(returnValue instanceof List)) {
            throw new RuntimeException(methodName + " 方法返回值类型必须为 List 及其子类");
        }
        // 如果数据为空 直接返回

        List<?> result = (List<?>) returnValue;
        if (result.isEmpty()) {
            return returnValue;
        }

        // 获取注解中的属性
        String fileName = exportExcel.value();
        String prefix = FileUtil.getPrefix(fileName);
        String suffix = FileUtil.getSuffix(fileName);
        String newFileName = prefix + "-" + System.currentTimeMillis() + "." + suffix;
        String fileAddress = exportExcel.exportAddress();
        String fileExportPath = fileAddress + "\\" + newFileName;
        System.out.println("文件导出地址：" + fileExportPath);
        System.out.println("------------------环绕通知执行--------------------");
        System.out.println("返回值: " + returnValue);

        exportData(result, fileExportPath);

        // 返回方法的返回值
        return returnValue;
    }

    /**
     * 导出数据
     *
     * @param result            数据
     * @param exportFileAddress 导出文件地址
     */
    private static void exportData(List<?> result, String exportFileAddress) {
        // 通过工具类创建writer
        ExcelWriter writer = ExcelUtil.getWriter(exportFileAddress);
        // 合并单元格后的标题行，使用默认标题样式
        writer.merge(4, "导出数据");
        // 一次性写出内容，使用默认样式，强制输出标题
        writer.write(result, true);
        // 关闭writer，释放内存
        writer.close();
    }

}
